package com.atguigu.juc.homework3;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


class MySelf{
   volatile   Map<String,String> map = new HashMap<>();
   /* Lock lock=new ReentrantLock();
    public void write(String key,String value){
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+" 准备写入");
            String put = map.put(key, value);
            System.out.println(Thread.currentThread().getName()+" 写入完成"+put);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }

    public void read(String key){
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+" 准备读入");
            String result = map.get(key);
            System.out.println(Thread.currentThread().getName()+" 读入完成"+result);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            lock.unlock();
        }
    }*/
        private ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock();
    public void write(String key,String value){
        readWriteLock.writeLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+" 准备写入");
            String put = map.put(key, value);
            System.out.println(Thread.currentThread().getName()+" 写入完成"+put);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            readWriteLock.writeLock().unlock();
        }
    }

    public void read(String key){
        readWriteLock.readLock().lock();
        try {
            System.out.println(Thread.currentThread().getName()+" 准备读入");
            String result = map.get(key);
            System.out.println(Thread.currentThread().getName()+" 读入完成"+result);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            readWriteLock.readLock().unlock();
        }
    }
}
/**
 * @auther zzyy
 * @create 2020-03-26 12:37
 *
 * 读写锁
 *
 * 对于同一个资源，我们涉及多线程的操作，有读，有写，交替进行。
 * 为了保证读写的数据一致性。
 *
 * 读 读 可共享
 * 读 写 不共享
 * 写 写 不共享
 * 读的时候希望高并发同时进行，可以共享，可以多个线程同时操作进行中.....
 * 写的时候为了保证数据一致性，需要独占排它。
 *
 *
 * 题目：5个线程读，5个线程写入，操作同一个资源
 *
 *
 * 1 不加锁                不可以，写的时候原子性被破坏
 * 2 加ReentrantLock锁     写控制了，但是没有并发度，并发性能不好
 * 3 加读写锁               规范写入，写唯一，读并发
 *
 * 普通的lock锁对于读写都是唯一
 * 其实在项目中效率最高的是读写分离
 * 读科院共享
 * 写独占排
 *
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) {
            MySelf mySelf=new MySelf();
        for (int i = 1; i <=5 ; i++) {
            int finalI = i;
            new Thread(() -> {
                mySelf.write(finalI+"",finalI+"");
            }, String.valueOf(i)).start();
        }

        for (int i = 1; i <=5 ; i++) {
            int finalI = i;
            new Thread(() -> {
                mySelf.read(finalI+"");
            }, String.valueOf(i)).start();
        }
    }
}
